package b649a01.poperators;

import java.util.Hashtable;
import java.util.StringTokenizer;

import b649a01.runners.sim_p;

/***
 * Integer move calculator.
 * 
 * @author Chao Sun
 * @version 1.0
 */
public class move extends calculator {
	private int s;
	private double t;
	
	/**
	 * Constructor.
	 */
	public move(sim_p sim, int i, int j, String op) {
		super(sim, i, j, op);
		Hashtable<String, Integer> cycleHash = simulator.getcycleHash();
		this.cycleNum = cycleHash.get(op);
		busyComUnit = "ADD";
	}
	
	/**
	 * Set locks to registers. Set computing unit lock.
	 * 
	 * @param opTokenizer
	 *          the string tokenizer containing all the operands
	 */
	@Override
	public void fetchRegs(StringTokenizer opTokenizer) {
		// add computing unit lock
		comUnitProperty.put("unit", busyComUnit);
		comUnitProperty.put("pipeIndex", pipelineIndex);
		simulator.addbusyComUnits(this, comUnitProperty);
		// get register names and indexes
		source1 = opTokenizer.nextToken();
		target = opTokenizer.nextToken();
		s1Index = Integer.parseInt(source1.substring(1));
		tIndex = Integer.parseInt(target.substring(1));
		// update read and write registers, both local and in main processor
		readRegs.add(source1);
		readRegProperty.put("vector", readRegs);
		readRegProperty.put("pipeIndex", pipelineIndex);
		simulator.aadreadRegs(this, readRegProperty);
		writeRegs.add(target);
		writeRegProperty.put("vector", writeRegs);
		writeRegProperty.put("pipeIndex", pipelineIndex);
		simulator.addwriteRegs(this, writeRegProperty);
	}
	
	/**
	 * Assign values to registers unless there is RAW hazard. Remove read locks.
	 */
	@Override
	public void assignRegs() {
		R = simulator.getR();
		s = R[s1Index];
		simulator.removereadRegs(readRegProperty); // remove read register lock
		readRegs.clear();
	}
	
	/**
	 * Execute an arithmetic instruction. Remove computing unit lock.
	 */
	@Override
	public void execute() {
		if (!finishFlag) {
			t = (double) s;
			finishFlag = true;
		}

		cycleNum--;
	}
	
	/**
	 * Write results into register. Remove write locks.
	 */
	@Override
	public void writeBack() {
		simulator.wbF(t, tIndex);
		simulator.removewriteRegs(writeRegProperty);
		writeRegs.clear();
		aliveFlag = false;
	}
	
}